package tech.dongliang.juduocai.upload.controller.utils;

import com.alibaba.fastjson.JSONObject;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.Thumbnails.Builder;
import net.coobird.thumbnailator.geometry.Positions;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import tech.fanslink.common.enums.EBizError;
import tech.fanslink.common.exceptions.BizException;
import tech.fanslink.utils.date.DateUtil;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Arrays;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class FileUtils {

    private static final String FILE_TYPE = "files";
    private static final String IMG_TYPE = "images";
    private static final String[] image = {"gif", "jpg", "jpeg", "png", "bmp"};

    public static void resize(File source, String dest, int width, int height) throws Exception {
        BufferedImage image = ImageIO.read(source);
        Builder<BufferedImage> builder = null;
        int imageWidth = image.getWidth();
        int imageHeitht = image.getHeight();
        if ((float) width / height != (float) imageWidth / imageHeitht) {
            if (imageWidth > imageHeitht) {
                image = Thumbnails.of(source).height(height).asBufferedImage();
            } else {
                image = Thumbnails.of(source).width(width).asBufferedImage();
            }
            builder = Thumbnails.of(image).sourceRegion(Positions.TOP_CENTER, width, height).size(width, height).outputFormat("jpg");
        } else {
            builder = Thumbnails.of(image).outputFormat("jpg").size(width, height);
        }
        builder.toFile(dest);
    }


    public static String[] getSavePathByRequest(HttpServletRequest request, boolean isImg) {
        String root = (String) request.getAttribute("root");
        String pathfix = (String) request.getAttribute("pathfix");
        String type = isImg ? IMG_TYPE : FILE_TYPE;
        String dateStr = DateUtil.formatDateByFormat(new Date(), "yyyyMMdd");
        // 拼凑 存储物理路径
        String savePath = root + type + File.separator + pathfix + File.separator + dateStr;
        // 拼凑 url
        String urlPath = "/" + type + "/" + pathfix + "/" + dateStr;

        String[] result = new String[]{savePath, urlPath};
        return result;
    }

    /**
     * @param imgFile 文件
     * @param paths   路径 0物理 1 URL
     * @returned JsonObject
     */
    public static JSONObject saveImage(MultipartFile imgFile, String[] paths) throws Exception {
        JSONObject obj = new JSONObject();
        try {
            // 存储物理路径
            String savePath = paths[0];
            // 返回的url
            String urlPath = paths[1];
            String newFileName = "";// 新的文件名
            String upFileName = imgFile.getOriginalFilename();
            // 保存第一张图片
            if (StringUtils.isNotEmpty(upFileName)) {
                if (!checkFileName(upFileName)) {
                    throw new BizException(EBizError.UPLOAD_ERROR, "上传文件扩展名不允许。\n只允许 gif,jpg,jpeg,png,bmp格式");
                }
                // 新文件名
                newFileName = getRandomFileName();
                // 锁结束
                File isD = new File(savePath);
                // 校验如果目录不存在，则创建目录
                if (!isD.exists() || !isD.isDirectory()) {
                    isD.mkdirs();
                }
                String saveFilename = savePath + File.separator + newFileName;
                // 保存文件
                Thumbnails.of(imgFile.getInputStream()).scale(1f).outputFormat("jpg").toFile(saveFilename);
                obj.put("success", true);
                urlPath = urlPath + "/" + newFileName + ".jpg";
                obj.put("url", urlPath);
            } else {
                throw new BizException(EBizError.UPLOAD_ERROR, "文件名为空");
            }

            return obj;
        } catch (Exception e) {
            throw new BizException(EBizError.UPLOAD_ERROR, "上传异常，请稍后再试");
        }
    }

    public static JSONObject saveFile(MultipartFile imgFile, String[] paths) {
        JSONObject obj = new JSONObject();
        try {
            // 存储物理路径
            String savePath = paths[0];
            // 返回的url
            String urlPath = paths[1];
            String newFileName = "";// 新的文件名
            String upFileName = imgFile.getOriginalFilename();
            // 保存第一张图片
            if (StringUtils.isNotEmpty(upFileName)) {
                // 新文件名
                newFileName = getRandomFileNameString(upFileName);
                // 锁结束
                File isD = new File(savePath);
                // 校验如果目录不存在，则创建目录
                if (!isD.exists() || !isD.isDirectory()) {
                    isD.mkdirs();
                }
                String saveFilename = savePath + File.separator + newFileName;
                File file = new File(saveFilename);
                // 保存文件
                imgFile.transferTo(file);
                if(file.exists()){
                    file.setReadable(true,false);
                }
                obj.put("success", true);
                urlPath = urlPath + "/" + newFileName;
                obj.put("url", urlPath);
            } else {
                throw new BizException(EBizError.UPLOAD_ERROR, "文件名为空");
            }

            return obj;
        } catch (Exception e) {
            throw new BizException(EBizError.UPLOAD_ERROR, "上传异常，请稍后再试");
        }
    }

    /**
     * 检查是否是符合的后缀名
     *
     * @param fileName
     * @return
     */
    public static boolean checkFileName(String fileName) {
        // 检查扩展名
        String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
        if (!Arrays.<String>asList(image).contains(fileExt)) {
            return false;
        }
        return true;
    }

    /**
     * 获得随机的数字为文件名，有效防止文件名重读
     *
     * @param fileName 传来的文件名
     *                 用户id
     * @return 返回新的文件名
     */
    public static String getRandomFileNameString(String fileName) {
        StringBuffer buffer = new StringBuffer();
        // 加锁为防止文件名重复
        final Lock lock = new ReentrantLock();
        lock.lock();
        try {
            buffer.append(System.currentTimeMillis());// 当前时间
            // 增加6位随机的数字
            buffer.append(getRandomString(6));
            // 添加后缀名
            buffer.append(fileName.substring(fileName.lastIndexOf("."), fileName.length()));
        } finally {
            lock.unlock();
        }
        return buffer.toString();
    }

    public static String getRandomFileName() {
        StringBuffer buffer = new StringBuffer();
        // 加锁为防止文件名重复
        final Lock lock = new ReentrantLock();
        lock.lock();
        try {
            buffer.append(System.currentTimeMillis());// 当前时间
            // 增加6位随机的数字
            buffer.append(getRandomString(6));
        } finally {
            lock.unlock();
        }
        return buffer.toString();
    }

    /**
     * 获取指定长度的随机数字
     *
     * @param len
     * @return
     */
    public static String getRandomString(int len) {
        Random random = new Random();
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < len; i++) {
            buffer.append(random.nextInt(10));
            random = new Random();
        }
        return buffer.toString();
    }
}
